Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the concept of a dedicated Router and custom Routes #12

Merged
merged 4 commits into from
Mar 20, 2024
Merged

Conversation

jayohms
Copy link
Contributor

@jayohms jayohms commented Mar 20, 2024

This introduces the concept of a Router with app-provided Route implementations that determine:

  • Whether the location matches the Route
  • Whether or not a location url should be routed through in-app navigation
  • Any custom behavior to perform if the location url won't be navigated through in-app navigation (such as routing to an external browser, opening mailto: links, etc).

The Route interface looks like this:

    interface Route {
        /**
         * The configured app url. You can use this to determine if a location
         * exists on the same domain.
         */
        val appUrl get() = Hotwire.appUrl

        /**
         * The route name used in debug logging.
         */
        val name: String

        /**
         * To permit in-app navigation when the location matches this route,
         * return [RouteResult.NAVIGATE]. To prevent in-app navigation return
         * [RouteResult.STOP].
         */
        val result: RouteResult

        /**
         * Determines whether the location matches this route. Use your own custom
         * rules based on the location's domain, protocol, path, or any other
         * factors.
         */
        fun matches(location: String): Boolean

        /**
         * Perform custom routing behavior when a match is found. For example,
         * open an external browser or app for external domain urls.
         */
        fun perform(location: String, activity: AppCompatActivity)
    }

Before performing an in-app navigation visit, TurboNavigator routes the location url through the app router. The router loops over each registered Route until it gets a match (the order of the registered routes determine in what order they're processed). The matched Route must return one of either:

  • RouteResult.NAVIGATE: Informs the navigator to continue performing the in-app navigation visit.
  • RouteResult.STOP: Informs the navigator to stop the in-app navigation visit. The Route can provide its own custom behavior, such as opening an external browser.

There are three built-in Routes that can be used by applications

  • AppNavigationRoute: Allows locations urls on the same domain as Hotwire.appUrl to navigate within the app.
  • BrowserRoute: Allows location urls on a different domain from Hotwire.appUrl to stop in-app navigation and route the url to an external browser.
  • BrowserTabRoute: Allows location urls on a different domain as Hotwire.appUrl to stop in-app navigation and route the url to a browser Custom Tab.

By default, AppNavigationRoute and BrowserRoute are registered. The routes that an application uses can be configured by calling Hotwire.registerRoutes(routes). Applications can create their own Route implementations by implementing the Route interface and registering the route.

@jayohms jayohms merged commit efb32a0 into main Mar 20, 2024
@jayohms jayohms deleted the router branch March 20, 2024 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant